1 module hip.filesystem.systems.cstd;
2 import hip.api.filesystem.hipfs;
3 
4 
5 /**
6 *   All those string allocations should be removed or turnt into @nogc somehow. The better cached, the best.
7 *
8 */
9 class HipCStdioFileSystemInteraction : IHipFileSystemInteraction
10 {
11     version(Windows)
12         pragma(lib, "Shlwapi.lib"); //PathIsDirectory
13     bool read(string path, void delegate(ubyte[] data) onSuccess, void delegate(string err) onError)
14     {
15         import core.stdc.stdio;
16         import hip.error.handler;
17         import hip.util.conv;
18         if(ErrorHandler.assertLazyErrorMessage(exists(path), "FileSystem Error:", "Filed named '"~path~"' does not exists"))
19             return false;
20 
21         auto f = fopen((path~"\0").ptr, "rb");
22         if(f is null)
23         {
24             onError("File not found.");
25             return false;
26         }
27         if(fseek(f, 0, SEEK_END))
28         {
29             fclose(f);
30             onError("Could not seek to file end.");
31             return false;
32         }
33         auto size = ftell(f);
34 
35         if(size <= 0)
36         {
37             fclose(f);
38             onError("Size <= 0 on file "~path);
39             return false;
40         }
41         if(fseek(f, 0, SEEK_SET))
42         {
43             fclose(f);
44             onError("Could not seek to file beginning");
45             return false;
46         }
47         ubyte[] output = new ubyte[size];
48 
49         if(size_t readed = fread(cast(void*)output.ptr, 1, cast(size_t)size, f) != size)
50         {
51             fclose(f);
52             onError("File is corrupted. Could not read file entirely (Readed "~to!string(readed)~") Expected "~to!string(size));
53             return false;
54         }
55         fclose(f);
56         onSuccess(output);
57         return true;
58     }
59     bool write(string path, void[] data)
60     {
61         import core.stdc.stdio;
62         if(exists(path))
63         {
64             auto file = fopen(cachedStringz(path), "w");
65             scope(exit)
66                 fclose(file);
67             if(fwrite(data.ptr, 1, data.length, file) != data.length)
68             {
69                 return fflush(file) == 0;
70             }
71             return true;
72         }
73         return false;
74     }
75     bool exists(string path)
76     {
77         import core.stdc.stdio;
78         if(auto file = fopen(cachedStringz(path), "r"))
79         {
80             fclose(file);
81             return true;
82         }
83         return false;
84     }
85     bool remove(string path)
86     {
87         static import core.stdc.stdio;
88         if(exists(path))
89         {
90             return core.stdc.stdio.remove(cachedStringz(path)) == 0;
91         }
92 
93         return false;
94     }
95     version(Posix)
96         import core.sys.posix.sys.stat;
97     else version(Windows)
98         import core.sys.windows.shlwapi : PathIsDirectoryA;
99     bool isDir(string path)
100     {
101         version(Windows)
102         {
103             return PathIsDirectoryA(cachedStringz(path)) == 1;
104         }
105         else version(Posix)
106         {
107             stat_t st;
108             stat(cachedStringz(path), &st);
109             return S_ISDIR(st.st_mode);
110         }
111         else return path[$-1] == '/';
112     }
113     
114 }